﻿using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Data;

namespace CommonUtils
{
    public static class DbUtil
    {
        /// <summary>
        /// 转为数据表 数据类型很准 拿不到注释
        /// </summary>
        public static DataTable GetDataTable(this IDataReader reader)
        {
            var table = new DataTable();
            var schema = reader.GetSchemaTable();

            //var info = new StringBuilder();
            //for (int index = 0; index < schema.Columns.Count; index++)
            //    info.AppendLine("//schema Columns index [{0}] type [{1}] name [{2}]", index, schema.Columns[index].DataType, schema.Columns[index].ColumnName);
            //info.Print();

            //schema Columns index [0] type [System.String] name [ColumnName]
            //schema Columns index [1] type [System.Int32] name [ColumnOrdinal]
            //schema Columns index [2] type [System.Int32] name [ColumnSize]
            //schema Columns index [3] type [System.Int16] name [NumericPrecision]
            //schema Columns index [4] type [System.Int16] name [NumericScale]
            //schema Columns index [5] type [System.Type] name [DataType]
            //schema Columns index [6] type [System.Int32] name [ProviderType]
            //schema Columns index [7] type [System.Boolean] name [IsLong]
            //schema Columns index [8] type [System.Boolean] name [AllowDBNull]
            //schema Columns index [9] type [System.Boolean] name [IsReadOnly]
            //schema Columns index [10] type [System.Boolean] name [IsRowVersion]
            //schema Columns index [11] type [System.Boolean] name [IsUnique]
            //schema Columns index [12] type [System.Boolean] name [IsKey]
            //schema Columns index [13] type [System.Boolean] name [IsAutoIncrement]
            //schema Columns index [14] type [System.String] name [BaseSchemaName]
            //schema Columns index [15] type [System.String] name [BaseCatalogName]
            //schema Columns index [16] type [System.String] name [BaseTableName]
            //schema Columns index [17] type [System.String] name [BaseColumnName]

            //Columns
            foreach (DataRow row in schema.Rows)
            {
                var column = table.Columns.Add((string)row["ColumnName"], (Type)row["DataType"]);
                column.AllowDBNull = (bool)row["AllowDBNull"];
                //column.Prefix = (string)row[?];  字段注释缺失 Db.GetColumnsSchema()中有注释
            }

            //Rows
            while (reader.Read())
            {
                var values = new object[reader.FieldCount];
                reader.GetValues(values);
                table.Rows.Add(values);
            }

            reader.Close();
            return table;
        }

        /// <summary>
        /// 转为Newtonsoft.Json.Linq.JArray
        /// </summary>
        public static JArray GetJArray(this IDataReader reader)
        {
            var jArray = new JArray();
            while (reader.Read())
            {
                var jObject = new JObject();
                for (int index = 0; index < reader.FieldCount; index++)
                    jObject.Put(reader.GetName(index), reader.GetValue(index));
                jArray.Add(jObject);
            }
            reader.Close();
            return jArray;
        }

        public static T[] GetArray<T>(this IDataReader reader)
        => reader.GetJArray().ToArray<T>();

        public static DataRow GetDataRow(this IDataReader reader)
        => reader.GetDataTable().Rows[0];

        /// <summary>
        /// 转为Newtonsoft.Json.Linq.JObject
        /// </summary>
        public static JObject GetJObject(this IDataReader reader)
        {
            JObject jObject = null;
            if (reader.Read())
            {
                jObject = new JObject();
                for (int index = 0; index < reader.FieldCount; index++)
                    jObject.Put(reader.GetName(index), reader.GetValue(index));
            }
            reader.Close();
            return jObject;
        }

        public static T GetObject<T>(this IDataReader reader)
        => reader.GetJObject().ToObject<T>();

        /// <summary>
        /// 转为基本数据类型数组
        /// </summary>
        public static T[] GetValues<T>(this IDataReader reader)
        {
            var array = new List<T>();
            while (reader.Read())
                array.Add((T)reader[0]);
            reader.Close();
            return array.ToArray();
        }

        /// <summary>
        /// 获取value
        /// </summary>
        public static object GetValue(this IDataReader reader)
        {
            object value = null;
            if (reader.Read())
                value = reader[0];
            reader.Close();
            return value;
        }

        public static T GetValue<T>(this IDataReader reader)
        => (T)reader.GetValue();

        /// <summary>
        /// 获取String
        /// </summary>
        public static string GetString(this IDataReader reader)
        => reader.GetValue().ToString();

        /// <summary>
        /// 获取Int
        /// </summary>
        public static int GetInt(this IDataReader reader)
        => reader.GetValue().ToInt();

        /// <summary>
        /// 获取value
        /// </summary>
        public static object GetValue(this IDataReader reader, string columnName)
        {
            object value = null;
            if (reader.Read())
                value = reader[columnName];
            reader.Close();
            return value;
        }

        public static T GetValue<T>(this IDataReader reader, string columnName)
        => (T)reader.GetValue(columnName);

        /// <summary>
        /// 获取String
        /// </summary>
        public static string GetString(this IDataReader reader, string columnName)
        => reader.GetValue(columnName).ToString();

        /// <summary>
        /// 获取Int
        /// </summary>
        public static int GetInt(this IDataReader reader, string columnName)
        => reader.GetValue(columnName).ToInt();

        /// <summary>
        /// 获取Long
        /// </summary>
        public static long GetLong(this IDataReader reader, string columnName)
        => reader.GetValue(columnName).ToLong();

        /// <summary>
        /// 获取Bool
        /// </summary>
        public static bool GetBoolen(this IDataReader reader, string columnName)
        => reader.GetValue(columnName).ToBoolean();

        /// <summary>
        /// 获取时间
        /// </summary>
        public static DateTime GetTime(this IDataReader reader, string columnName)
        => reader.GetValue(columnName).ToTime();

        /// <summary>
        /// 获取枚举
        /// </summary>
        public static T GetEnum<T>(this IDataReader reader, string columnName)
        => reader.GetValue(columnName).ToEnum<T>();

        //字段开始标识
        public const char MySqlFieldStartIdentifier = '`';

        //字段结束标识
        public const char MySqlFieldEndIdentifier = '`';

        public static char GetFieldStartIdentifier(string dbType)
        {
            switch (dbType)
            {
                case "MySql":
                case "MySql.EntityFrameworkCore":
                    return MySqlFieldStartIdentifier;
            }
        (dbType + "数据库字段开始标识返回默认值").Print();
            return '\"';
        }
        public static char GetFieldEndIdentifier(string dbType)
        {
            switch (dbType)
            {
                case "MySql":
                case "MySql.EntityFrameworkCore":
                    return MySqlFieldEndIdentifier;
            }
           (dbType + "数据库字段结束标识返回默认值").Print();
            return '\"';
        }
    }
}
